
var empty_params = ['','','','','',''],
    source_list = ['GEXP','METH','CNVR','CLIN'],
    source_map = pv.numerate(source_list),
    link_sources_colors = pv.Colors.category20(),
    linear_unit = 100000,
    proximal_distance = 2.5 * linear_unit,

    source_color_scale=  pv.Colors.category10();

node_colors = function(source) { return source_color_scale(source_map[source]);}

function loadFilteredData(query_params) {
    var query = buildGQLQuery(query_params);
    loadData(query,function(){loadNetworkData(query_params,renderCircleData);});
}

function renderCircleData() {
    wedge_plot(document.getElementById('circle-panel'));
}

function renderLinearData(chr,start,range_length) {
    linear_plot(document.getElementById('linear-panel'),chr,start,range_length);
}

function inter_chrom_click(node) {
    var node1 = vq.utils.VisUtils.extend({start:node.target_start,end:node.target_end},node);
    var link ={sourceNode:node1, targetNode:node.partner};
    initiateScatterplot(link);
}

function initiateScatterplot(link) {
    loadFeatureData(link,function() {renderScatterPlot(link);});
}



function wedge_plot(div) {
    var width=800, height=800;
    var	ring_radius = width / 20;
    var chrom_keys = ["1","2","3","4","5","6","7","8","9","10",
        "11","12","13","14","15","16","17","18","19","20","21","22","X","Y"];

    function genome_listener(chr) {
            renderLinearData(chr);
        }

    function wedge_listener(feature) {
                    var chr = feature.chr;
                    var start = bpToHKbp(feature.start) - 2.5;
                    var range_length = bpToHKbp(feature.end) - start + 2.5;
                    renderLinearData(chr,start,range_length);
                }

        var ucsc_genome_url = 'http://genome.ucsc.edu/cgi-bin/hgTracks';
          var tick_listener = function(feature){
              window.open(ucsc_genome_url + '?position=chr' + feature.chr + ':' + (feature.start) +
                      '-'+ (feature.end ? feature.end : feature.start + linear_unit),'_blank');
              return false;
              };

       var ranking_tooltip_items = {
           Feature : 'label',
           Type : 'type',
            Rank : 'value',
           Weight: 'options',
            Chr : 'chr',
            Location :  function(feature) { return bpToHKbp(feature.start).toFixed(0) + '-' + bpToHKbp(feature.end).toFixed(0) + ' 100kb';}

        },
        unlocated_tooltip_items = {
            Feature :  function(feature) { return feature.source + ' ' + feature.label;}

        };
    var chrom_leng = vq.utils.VisUtils.clone(annotations['chrom_leng']);

    var ring = vq.utils.VisUtils.clone(args['features']).filter(function(feature) { return feature.chr != '' && feature.rank != '';})
           .map(function(feature) { return vq.utils.VisUtils.extend(feature,{value:feature.rank, options:feature.weight});});
    var weight_color = pv.Scale.linear(ring.map(function(feature) { return feature.options;})).range('blue','red');

    var ticks = vq.utils.VisUtils.clone(args['features']);

    var unlocated_map = parsed_data['unlocated'].filter(function(link) { return  link.node1.chr != '';})
            .map(function(link) {
      return  vq.utils.VisUtils.extend(link.node2,{chr:link.node1.chr, start:link.node1.start,end:link.node2.end, value: 0});
    });

    var data = {
        GENOME: {
            DATA:{
                key_order : chrom_keys,
                key_length : chrom_leng
            },
            OPTIONS: {
                radial_grid_line_width: 1,
                label_layout_style : 'clock',
                listener : genome_listener,
                label_font_style : '20pt helvetica bold'
            }
        },
        TICKS : {
            DATA : {
                data_array : ticks
            },
            OPTIONS :{
                 display_legend : false,
                listener : tick_listener,
                fill_style : function(tick) {return node_colors(tick.source); },
                tooltip_items : {Tick : function(node) { return node.label+ ' ' + node.source + ' Chr' + node.chr + ' ' + node.start +
                            '-' + node.end;}}
            }
        },
        PLOT: {
            width : width,
            height :  height,
            horizontal_padding : 30,
            vertical_padding : 30,
            container : div,
            enable_pan : false,
            enable_zoom : false,
            show_legend: true,
            legend_include_genome : true,
            legend_corner : 'ne',
            legend_radius  : width / 15
        },
           WEDGE:[
            {
                PLOT : {
                    height : ring_radius,
                    type :   'histogram'
                },
                DATA:{
                    data_array : ring
                },
                OPTIONS: {
                    legend_label : 'Target Features' ,
                    legend_description : 'Rank and Weight of Target Feature',
                    outer_padding : 10,
                    base_value : 0,
                    min_value : 0,
                    fill_style : function(feature) { return weight_color(feature.options);},
                    stroke_style : function(feature) { return weight_color(feature.options);},
                    tooltip_items : ranking_tooltip_items,
                    listener : wedge_listener
                }
            },{
                    PLOT : {
                    height : ring_radius/2,
                    type :   'scatterplot'
                },
                DATA:{
                    data_array : unlocated_map
                },
                OPTIONS: {
                    legend_label : 'Unmapped Predictive Features' ,
                    legend_description : 'Predictive Features with No Positional Mapping',
                    outer_padding : 10,
                    base_value : 0,
                    min_value : -1,
                    max_value : 1,
                    radius : 4,
                    draw_axes : false,
                    shape:'dot',
                    fill_style  : function(feature) {return node_colors(feature.source); },
                    stroke_style : function(feature) {return node_colors(feature.source); },
                    tooltip_items : unlocated_tooltip_items,
                    listener : wedge_listener
                }
            }

        ],

        NETWORK:{
            DATA:{
                data_array : parsed_data['network']
            },
            OPTIONS: {
                outer_padding : 20,
                node_highlight_mode : 'isolate',
                node_fill_style : 'ticks',
                node_key : function(node) { return node['label'];},
                link_listener: initiateScatterplot,
                link_fill_style : function(link) {
                    return link_sources_colors(source_map[link.sourceNode.source] * (source_list.length) + source_map[link.targetNode.source]);},
                constant_link_alpha : 0.7,
                node_tooltip_items :  {Node : function(node) { return node.label+ ' ' + node.source + ' Chr' + node.chr + ' ' + node.start +
                            '-' + node.end;}},
                link_tooltip_items :  {
                    'Target' : function(link) { return link.sourceNode.label+ ' ' + link.sourceNode.source + ' Chr' + link.sourceNode.chr + ' ' + link.sourceNode.start +
                            '-' + link.sourceNode.end;},

                    'Predictor' : function(link) { return link.targetNode.label+ ' ' + link.targetNode.source + ' Chr' + link.targetNode.chr + ' ' + link.targetNode.start +
                            '-' + link.targetNode.end;},
                    'Importance' : 'importance',
                    Correlation : 'correlation'
                }
            }
        }
    };

    var circle_vis = new vq.CircVis();
    var dataObject ={DATATYPE : "vq.models.CircVisData", CONTENTS : data };

    circle_vis.draw(dataObject);
    return circle_vis;
}

function bpToHKbp(bp) {
    return bp != null ? (bp == 0 ? 0 : bp / 100000): null;
}

function hundredKbpToBp(num) {
    return Math.floor(num* 100000);
}

function linear_plot(div,chrom,start,range_length) {
     var ucsc_genome_url = 'http://genome.ucsc.edu/cgi-bin/hgTracks';
          var tile_listener = function(feature){
              window.open(ucsc_genome_url + '?position=chr' + feature.chr + ':' + hundredKbpToBp(feature.start) +
                      '-'+ hundredKbpToBp(feature.end),'_blank');
              return false;
              };
    var spot_listener = function(feature){
              window.open(ucsc_genome_url + '?position=chr' + feature.chr + ':' + hundredKbpToBp(feature.start)  +
                      '-'+ hundredKbpToBp(feature.start+ 20),'_blank');
              return false;
              };

     var unlocated_tooltip_items = {
            Target : function(tie) {
            return tie.label + ' ' + tie.source + ' Chr' +tie.chr},
        Predictor : function(tie) {
          return tie.partner.label + ' ' + tie.partner.source },
         'Importance' : 'importance',
         Correlation : 'correlation'

        },
        located_tooltip_items = {
            Target : function(tie) {
            return tie.label + ' ' + tie.source + ' Chr' +tie.chr + ' ' +tie.start +'-'+tie.end;}
        },
        inter_tooltip_items = {
            Target : function(tie) {
            return tie.label + ' ' + tie.source + ' Chr' +tie.chr + ' ' +tie.target_start +'-'+tie.target_end;},
        Predictor : function(tie) {
          return tie.partner.label + ' ' + tie.partner.source +
                  ' Chr' + tie.partner.chr+ ' ' +tie.partner.start +'-'+tie.partner.end;},
         'Importance' : 'importance',
         Correlation : 'correlation'

        };

    var hit_map = parsed_data['unlocated'].filter(function(link) { return  link.node1.chr == chrom;})
            .map(function(link) {
       var node = vq.utils.VisUtils.extend({},link.node1);
                node.start = bpToHKbp(node.start); node.end = bpToHKbp(node.end);
        node.partner = vq.utils.VisUtils.extend({},link.node2);
        return node;
    }).concat(parsed_data['unlocated'].filter(function(link) { return  link.node2.chr == chrom;})
            .map(function(link) {
       var node = vq.utils.VisUtils.extend({},link.node2);
                node.start = bpToHKbp(node.start); node.end = bpToHKbp(node.end);
        node.partner = vq.utils.VisUtils.extend({},link.node1);
        node.importance = link.importance,node.correlation = link.correlation;
        return node}));


    var tie_map = parsed_data['network'].filter(function(link) {
        return link.node1.chr == chrom && link.node2.chr == chrom &&
                Math.abs(link.node1.start - link.node2.start) > proximal_distance;})
            .map(function(link) {
     var node1_clone = vq.utils.VisUtils.extend({target_start:link.node1.start, target_end : link.node1.end},
             link.node1),
        node2_clone = vq.utils.VisUtils.extend({target_start:link.node2.start, target_end : link.node2.end},
             link.node2);
        node1_clone.start = link.node1.start <= link.node2.start ?
                link.node1.start : link.node2.start;
        node1_clone.end = link.node1.start <= link.node2.start ? link.node2.start : link.node1.start;
        node2_clone.start = bpToHKbp(node2_clone.start);node2_clone.end = bpToHKbp(node2_clone.end);
        node1_clone.start = bpToHKbp(node1_clone.start);node1_clone.end = bpToHKbp(node1_clone.end);
        node1_clone.target_start = bpToHKbp(node1_clone.target_start);node1_clone.target_end = bpToHKbp(node1_clone.target_end);
        node1_clone.partner = node2_clone;
        node1_clone.importance = link.importance,node1_clone.correlation = link.correlation;
        return node1_clone;
    });

    var neighbor_map = parsed_data['network'].filter(function(link) {
        return link.node1.chr == chrom && link.node2.chr == chrom &&
                Math.abs(link.node1.start - link.node2.start) < proximal_distance;})
            .map(function(link) {
     var node1_clone = vq.utils.VisUtils.extend({},link.node1),
        node2_clone = vq.utils.VisUtils.extend({},link.node2);
        node2_clone.start = bpToHKbp(node2_clone.start);node2_clone.end = bpToHKbp(node2_clone.end);
        node1_clone.start = bpToHKbp(node1_clone.start);node1_clone.end = bpToHKbp(node1_clone.end);
        node1_clone.partner = node2_clone;
        return node1_clone;
    });


    var locations = vq.utils.VisUtils.clone(args['features']).filter(function(node) { return node.chr == chrom;})
            .map(function (location)  {
    var node =location;
        node.start = bpToHKbp(node.start);node.end = bpToHKbp(node.end);
        return node;
    }).concat(pv.uniq(parsed_data['network'].filter(function(link) { return link.node2.chr == chrom;}).map(function(link) {
        var node = vq.utils.VisUtils.extend({},link.node2);
                node.start = bpToHKbp(node.start); node.end = bpToHKbp(node.end);
        return node;
    }),function(node){ return node.id;}));

    var data_obj = function() { return {
        PLOT :     {
            width:800,
            height:700,
            min_position:1,
            max_position:maxPos,
            vertical_padding:20,
            horizontal_padding:20,
            container : div,
            context_height: 100},
        TRACKS : [
            { type: 'tile',
                label : 'Feature Locations',
                description : 'Genome Location of Features',
                CONFIGURATION: {
                    fill_style : function(node) { return node_colors(node.source);},          //required
                    stroke_style : function(node) { return node_colors(node.source);},          //required
                    track_height : 50,           //required
                    tile_height:20,                //required
                    track_padding: 20,             //required
                    tile_padding:6,              //required
                    tile_overlap_distance:1,    //required
                    notifier:tile_listener,         //optional
                    tooltip_items :  located_tooltip_items     //optional
                },
                data_array : locations
            },  { type: 'glyph',
                label : 'Unmapped Feature Correlates',
                description : '',
                CONFIGURATION: {
                    fill_style : function(hit) { return node_colors(hit.partner.source);},
                    stroke_style : null,
                    track_height : 120,
                    track_padding: 20,
                    tile_padding:6,              //required
                    tile_overlap_distance:.1,    //required
                    shape :  'dot',
                    tile_show_all_tiles : true,
                    radius : 3,
                    notifier:spot_listener,
                  tooltip_items : unlocated_tooltip_items
                },
                data_array : hit_map
            },
                { type: 'glyph',
                label : 'Proximal Feature Predictors',
                description : '',
                CONFIGURATION: {
                    fill_style : function(hit) { return node_colors(hit.partner.source);},
                    stroke_style : null,
                    track_height : 80,
                    track_padding: 20,
                    tile_padding:4,              //required
                    tile_overlap_distance:1,    //required
                    shape :  'dot',
                    tile_show_all_tiles : true,
                    radius : 3,
                    notifier:spot_listener,
                  tooltip_items : inter_tooltip_items
                },
                data_array : neighbor_map
            },
            { type: 'tile',
                label : 'Distal Inter-Chromosomal Correlates',
                description : '',
                CONFIGURATION: {
                    fill_style :  function(hit) { return node_colors(hit.partner.source);},
                    stroke_style : function(hit) { return node_colors(hit.partner.source);},
                    track_height : 220,
                    track_padding: 10,             //required
                    tile_height : 2,
                    tile_padding:7,              //required
                    tile_overlap_distance:.1,    //required
                    tile_show_all_tiles : true,
                    notifier : inter_chrom_click,
                    tooltip_items : inter_tooltip_items
                },
                data_array : tie_map
            }]
    }
    };
    var chrom_leng = vq.utils.VisUtils.clone(annotations['chrom_leng']);
    var chr_match = chrom_leng.filter(function(chr_obj) { return chr_obj.chr_name == chrom;});
    var maxPos = Math.ceil(bpToHKbp(chr_match[0]['chr_length']));

    var lin_browser = new vq.LinearBrowser();
    var lin_data = {DATATYPE: 'vq.models.LinearBrowserData',CONTENTS: data_obj()};

    lin_browser.draw(lin_data);

    if (start != null && start > 0 && range_length != null && range_length > 0) {
        lin_browser.setFocusRange(start,range_length);
    }
      return lin_browser;
}

function scatterplot_draw(div) {

        var data = patients['data'][0];
    var patient_labels = annotations['patients'];
    var f1 = data.f1id, f2 = data.f2id,
            f1values = data.f1values.split(':').map(function(val) {return parseFloat(val);}),
            f2values = data.f2values.split(':').map(function(val) {return parseFloat(val);}),
    f1label = data.f1alias, f2label = data.f2alias;
    var data_array = [];
    for (var i=0; i< f1values.length; i++) {
        var obj = {};
        obj[f1] = f1values[i], obj[f2]=f2values[i], obj['patient_id'] = patient_labels[i];
        data_array.push(obj);
    }

    var tooltip = {};
    tooltip[data.f1alias] = f1,tooltip[data.f2alias] = f2,tooltip['Sample'] = 'patient_id';

           var sp = new vq.ScatterPlot();

        var config ={DATATYPE : "vq.models.ScatterPlotData", CONTENTS : {
            PLOT : {container: div,
                width : 400,
                height: 300,
            vertical_padding : 40, horizontal_padding: 40, font :"14px sans"},
            data_array: data_array,
            xcolumnid: f1,
            ycolumnid: f2,
            valuecolumnid: 'patient_id',
            xcolumnlabel : f1label,
            ycolumnlabel : f2label,
            valuecolumnlabel : 'Sample Id',
            tooltip_items : tooltip
        }};

        sp.draw(config);

}